<script setup lang="ts">
import {
  AlipayCircleFilled,
  LockOutlined,
  TaobaoCircleFilled,
  UserOutlined,
  WeiboCircleFilled,
} from '@ant-design/icons-vue'
import { delayTimer } from '@v-c/utils'
import { AxiosError } from 'axios'
import GlobalLayoutFooter from '~/layouts/components/global-footer/index.vue'
import { getQueryParam } from '~/utils/tools'
import pageBubble from '@/utils/page-bubble'
import { getCodeImg, getTenantList, login } from '~/api/login.ts'
import type { LoginData, TenantVO } from '~/api/types.ts'

const notification = useNotification()
const appStore = useAppStore()
const { layoutSetting } = storeToRefs(appStore)
const router = useRouter()
const token = useAuthorization()
// 验证码开关
const captchaEnabled = ref(true)
// 租户开关
const tenantEnabled = ref(true)
const codeUrl = ref('')
const tenantList = ref<TenantVO[]>([])
const loginModel = reactive<LoginData>({
  tenantId: '000000',
  username: 'admin',
  password: 'admin123',
  rememberMe: false,
  code: '',
  uuid: '',
} as LoginData)
const { t } = useI18nLocale()
const formRef = shallowRef()
const resetCounter = 60
const submitLoading = shallowRef(false)
const errorAlert = shallowRef(false)
const bubbleCanvas = ref<HTMLCanvasElement>()
const { pause } = useInterval(1000, {
  controls: true,
  immediate: false,
  callback(count) {
    if (count) {
      if (count === resetCounter)
        pause()
    }
  },
})

async function submit() {
  submitLoading.value = true
  const Loading = useLoading({ text: '正在登录...' })
  try {
    await formRef.value?.validate()
    // 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码
    if (loginModel.rememberMe) {
      localStorage.setItem('tenantId', String(loginModel.tenantId))
      localStorage.setItem('username', String(loginModel.username))
      localStorage.setItem('password', String(loginModel.password))
      localStorage.setItem('rememberMe', String(loginModel.rememberMe))
    }
    else {
      // 否则移除
      localStorage.removeItem('tenantId')
      localStorage.removeItem('username')
      localStorage.removeItem('password')
      localStorage.removeItem('rememberMe')
    }
    Loading.open()
    const { data } = await login(loginModel)
    token.value = data?.access_token
    Loading.close()
    notification.success({
      message: '登录成功',
      description: '欢迎回来！',
      duration: 3,
    })
    // 获取当前是否存在重定向的链接，如果存在就走重定向的地址
    const redirect = getQueryParam('redirect', '/')
    router.push({
      path: redirect,
      replace: true,
    })
  }
  catch (e) {
    getCode()
    Loading.close()
    if (e instanceof AxiosError)
      errorAlert.value = true

    submitLoading.value = false
  }
}

/**
 * 获取租户列表
 */
async function initTenantList() {
  const { data } = await getTenantList()
  tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled
  if (tenantEnabled.value) {
    tenantList.value = data.voList
    if (tenantList.value != null && tenantList.value.length !== 0)
      loginModel.tenantId = tenantList.value[0].tenantId
  }
}

/**
 * 获取验证码
 */
async function getCode() {
  const res = await getCodeImg()
  const { data } = res
  captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled
  if (captchaEnabled.value) {
    codeUrl.value = `data:image/gif;base64,${data.img}`
    loginModel.uuid = data.uuid
  }
}

// 检测租户选择框的变化
function getLoginData() {
  const tenantId = localStorage.getItem('tenantId')
  const username = localStorage.getItem('username')
  const password = localStorage.getItem('password')
  const rememberMe = localStorage.getItem('rememberMe')

  loginModel.tenantId = tenantId === null ? String(loginModel.tenantId) : tenantId
  loginModel.username = username === null ? String(loginModel.username) : username
  loginModel.password = password === null ? String(loginModel.password) : String(password)
  loginModel.rememberMe = rememberMe === null ? false : Boolean(rememberMe)
}

watch(
  () => loginModel.tenantId,
  () => {
    localStorage.setItem('tenantId', String(loginModel.tenantId))
  },
)

onMounted(async () => {
  await delayTimer(300)
  initTenantList()
  getCode()
  getLoginData()
  pageBubble.init(unref(bubbleCanvas)!)
})

onBeforeUnmount(() => {
  pageBubble.removeListeners()
})
</script>

<template>
  <div class="login-container">
    <div h-screen w-screen absolute z-10>
      <canvas ref="bubbleCanvas" />
    </div>
    <div class="login-content flex-center">
      <div class="ant-pro-form-login-main rounded">
        <!-- 登录头部 -->
        <div
          class="flex-between h-15 px-4 mb-[2px]"
        >
          <div class="flex-end">
            <span class="ant-pro-form-login-logo">
              <img w-full h-full object-cover src="/logo.svg">
            </span>
            <span class="ant-pro-form-login-title">
              Antdv Pro
            </span>
            <span class="ant-pro-form-login-desc">
              {{ t("pages.layouts.userLayout.title") }}
            </span>
          </div>
          <div class="login-lang flex-center relative z-11">
            <span
              class="flex-center cursor-pointer text-16px"
              @click="appStore.toggleTheme(layoutSetting.theme === 'dark' ? 'light' : 'dark')"
            >
              <!-- 亮色和暗黑模式切换按钮 -->
              <template v-if="layoutSetting.theme === 'light'">
                <carbon-moon />
              </template>
              <template v-else>
                <carbon-sun />
              </template>
            </span>
            <SelectLang />
          </div>
        </div>
        <a-divider m-0 />
        <!-- 登录主体 -->
        <div class="box-border flex min-h-[520px]">
          <!-- 登录框左侧 -->
          <div class="ant-pro-form-login-main-left min-h-[520px] flex-center  bg-[var(--bg-color-container)]">
            <img src="@/assets/images/login-left.png" class="h-5/6 w-5/6">
          </div>
          <a-divider m-0 type="vertical" class="ant-pro-login-divider  min-h-[520px]" />
          <!-- 登录框右侧 -->
          <div class="ant-pro-form-login-main-right px-5 w-[335px] flex-center flex-col relative z-11">
            <div class="text-center py-6 text-2xl">
              {{ t('pages.login.tips') }}
            </div>
            <a-form ref="formRef" :model="loginModel">
              <!-- 判断是否存在error -->
              <a-form-item v-if="tenantEnabled" prop="tenantId">
                <a-select
                  v-model:value="loginModel.tenantId" placeholder="请选择/输入公司名称"
                  style="width: 100%"
                >
                  <a-select-option
                    v-for="item in tenantList" :key="item.tenantId" :label="item.companyName"
                    :value="item.tenantId"
                  >
                    {{ item.companyName }}
                  </a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item name="username" :rules="[{ required: true, message: t('pages.login.username.required') }]">
                <a-input
                  v-model:value="loginModel.username" allow-clear
                  autocomplete="off"
                  :placeholder="t('pages.login.username.placeholder')" size="large" @press-enter="submit"
                >
                  <template #prefix>
                    <UserOutlined />
                  </template>
                </a-input>
              </a-form-item>
              <a-form-item name="password" :rules="[{ required: true, message: t('pages.login.password.required') }]">
                <a-input-password
                  v-model:value="loginModel.password" allow-clear
                  :placeholder="t('pages.login.password.placeholder')" size="large" @press-enter="submit"
                >
                  <template #prefix>
                    <LockOutlined />
                  </template>
                </a-input-password>
              </a-form-item>
              <a-form-item v-if="captchaEnabled" prop="code">
                <a-input
                  v-model:value="loginModel.code" size="large" auto-complete="off" placeholder="验证码"
                  style="width: 53%" @keyup.enter="submit"
                >
                  <template #prefix>
                    <svg-icon icon-class="validCode" class="el-input__icon input-icon" />
                  </template>
                </a-input>
                <div class="login-code">
                  <img :src="codeUrl" class="login-code-img" @click="getCode">
                </div>
              </a-form-item>
              <div class="mb-24px flex-between">
                <a-checkbox v-model:checked="loginModel.rememberMe">
                  {{ t('pages.login.rememberMe') }}
                </a-checkbox>
                <a>{{ t('pages.login.forgotPassword') }}</a>
              </div>
              <a-button type="primary" block :loading="submitLoading" size="large" @click="submit">
                {{ t('pages.login.submit') }}
              </a-button>
            </a-form>
            <a-divider>
              <span class="text-slate-500">{{ t('pages.login.loginWith') }}</span>
            </a-divider>
            <div class="ant-pro-form-login-other">
              <AlipayCircleFilled class="icon" />
              <TaobaoCircleFilled class="icon" />
              <WeiboCircleFilled class="icon" />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div py-24px px-50px fixed bottom-0 z-11 w-screen :data-theme="layoutSetting.theme" text-14px>
      <GlobalLayoutFooter
        :copyright="layoutSetting.copyright" icp="鲁ICP备2023021414号-2"
      >
        <template #renderFooterLinks>
          <footer-links />
        </template>
      </GlobalLayoutFooter>
    </div>
  </div>
</template>

<style lang="less" scoped>
.login-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: auto;
  background: var(--bg-color-container);
}

.login-lang {
  height: 40px;
  line-height: 44px;
}

.login-content {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.ant-pro-form-login-container {
  display: flex;
  flex: 1 1;
  flex-direction: column;
  height: 100%;
  padding: 32px 0;
  overflow: auto;
  background: inherit
}

.ant-pro-form-login-header a {
  text-decoration: none
}

.ant-pro-form-login-title {
  color: var(--text-color);
  font-weight: 600;
  font-size: 33px;
  line-height: 1;
}

.ant-pro-form-login-logo {
  width: 44px;
  height: 44px;
  margin-right: 16px;
  vertical-align: top
}

.ant-pro-form-login-desc {
  color: var(--text-color-1);
  font-size: 14px;
  margin-left: 16px
}

.ant-pro-form-login-main-right {
  .ant-tabs-nav-list {
    margin: 0 auto;
    font-size: 16px;
  }

  .ant-pro-form-login-other {
    line-height: 22px;
    text-align: center
  }

}

.ant-pro-form-login-main {
  box-shadow: var(--c-shadow);
}

.icon {
  margin-left: 8px;
  color: var(--text-color-2);
  font-size: 24px;
  vertical-align: middle;
  cursor: pointer;
  transition: color .3s;

  &:hover {
    color: var(--pro-ant-color-primary);
  }
}

.login-media(@width:100%) {
  .ant-pro-form-login-main {
    width: @width;
  }
  .ant-pro-form-login-main-left {
    display: none;
  }
  .ant-pro-form-login-main-right {
    width: 100%;
  }
  .ant-pro-form-login-desc {
    display: none;
  }
}

@media (min-width: 992px) {
  .ant-pro-form-login-main-left {
    width: 700px;
  }
}

@media (min-width: 768px) and (max-width: 991px) {
  .ant-pro-login-divider {
    display: none;
  }

  .login-media(400px)
}

.login-code {
  width: 40%;
  height: 40px;
  float: right;

  img {
    cursor: pointer;
    vertical-align: middle;
  }
}

.login-code-img {
  height: 40px;
  padding-left: 12px;
}

@media screen and (max-width: 767px) {
  .login-media(350px);

  .ant-pro-login-divider {
    display: none;
  }
}
</style>
